package com.next

import grails.converters.JSON
import grails.transaction.Transactional
import groovy.json.JsonOutput
import org.springframework.security.access.annotation.Secured

import java.text.SimpleDateFormat

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class UserController
{
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE", appLogin: "POST", appQueryUser: "POST"]

    def userService
    def passwordEncoder
    def liquidityRiskReportService
    def opportunityService
    def springSecurityService
    def fileServerService

    def index(Integer max)
    {
        params.max = Math.min(max ?: 10, 100)
        respond User.list(params), model: [userCount: User.count()]
    }

    @Transactional
    def searchUser()
    {
        def fullName = params["fullName"]
        def city = params["city"]
        def department = params["department"]

        String sql = "from User as u where 1=1"
        if (fullName)
        {
            sql += " and u.fullName like '%${fullName}%'"
        }
        if (city)
        {
            sql += " and u.city.name = '${city}'"
        }
        if (department)
        {
            sql += " and u.department.name = '${department}'"
        }

        String countSql = "select count(u.id) " + sql

        def list = User.findAll(sql, [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = User.executeQuery(countSql)

        respond list, model: [userCount: count[0], params: params], view: 'index'
    }

    def show(User user)
    {
        def contactList = Contact.findAllByUser(user)
        def userRoleList = UserRole.findAllByUser(user)
        def activityList = Activity.findAllByUserOrAssignedTo(user, user)
        respond user, model: [userRoleList: userRoleList, contactList: contactList, activityList: activityList]
    }

    def create()
    {
        def accounts = Account.findAllByActive(true)
        respond new User(params), model: [accounts: accounts]
    }

    @Transactional
    def save(User user)
    {
        if (user == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (user.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond user.errors, view: 'create'
            return
        }
        // user.code = userService.generateCode()

        user.save flush: true

        UserRole.create(user, Role.findByAuthority('ROLE_ACCOUNT_MANAGER'))

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'user.label', default: 'User'), user.id])
                redirect user
            }
            '*' { respond user, [status: CREATED] }
        }
    }

    def edit(User user)
    {
        def userrole = UserRole.findByUser(user)
        respond user, model: [userrole: userrole]
    }

    @Transactional
    def update(User user)
    {
        if (user == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (user.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond user.errors, view: 'edit'
            return
        }

        user.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'user.label', default: 'User'), user.id])
                redirect user
            }
            '*' { respond user, [status: OK] }
        }
    }

    @Transactional
    def deleteRole()
    {
        String userId = params["userId"]
        String roleId = params["roleId"]
        def userRole = UserRole.findByUserAndRole(User.findById(userId), Role.findById(roleId))

        if (userRole == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        userRole.delete flush: true

        respond User.list(params), model: [userCount: User.count()], view: "index"

        /*request.withFormat{
            form multipartForm{
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'userRole.label',
                default: 'userRole')])
                redirect action: "index", method: "GET"

            }
            '*'{render status: NO_CONTENT}
        }*/
    }

    @Transactional
    def delete(User user)
    {

        if (user == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        user.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'user.label', default: 'User'), user.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'user.label',
                                                                                          default: 'User'), params.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    def changePassword()
    {
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)
        respond user
    }

    @Transactional
    def updatePassword(User user)
    {
        def oldPassword = params['oldPassword']
        def newPassword = params['newPassword']

        if (passwordEncoder.isPasswordValid(user.password, oldPassword, null))
        {
            user.password = newPassword
            user.save flush: true
            render([status: "success"] as JSON)
        }
        else
        {
            flash.message = message(code: 'user.password.matches.invalid')
            // respond user, view: 'changePassword'
            render([status: "error", errorMessage: message(code: 'user.password.matches.invalid')] as JSON)
        }
    }

    @Transactional
    def resetPassword()
    {
        def user = User.findById(params['user'])
        def password = params['password']
        def destination = params['destination']
        user.password = password
        if (user.validate())
        {
            user.save flush: true
            flash.message = "密码重置成功"
            if (destination)
            {
                redirect controller: destination, action: 'index'
                return
            }
            else
            {
                redirect controller: 'userTeam', action: 'index'
                return
            }
        }
        else
        {
            flash.message = user.errors
            if (destination)
            {
                redirect controller: destination, action: 'index'
                return
            }
            else
            {
                redirect controller: 'userTeam', action: 'index'
                return
            }
        }
    }

    @Transactional
    def appLogin()
    {
        //助手端登录。
        def json = request.JSON

        def username = json['username']
        def password = json['password']
        if (!username)
        {
            def errors = [errorCode: 5262, errorMessage: "登录名不可空"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!password)
        {
            def errors = [errorCode: 5261, errorMessage: "密码不可空"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def user = User.findByUsername(username)
        if (!user)
        {
            def errors = [errorCode: 4500, errorMessage: "用户名不存在"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (passwordEncoder.isPasswordValid(user.password, password, null))
        {
            user.appSessionId = UUID.randomUUID().toString()

            user.save flush: true
            render JsonOutput.toJson([sessionId: user.appSessionId])
        }
        else
        {
            def errors = [errorCode: 4400, errorMessage: "用户名或口令错误"]
            render JsonOutput.toJson(errors), status: 400
        }

    }

    @Transactional
    def appQueryUser()
    {
        //助手端我的
        def json = request.JSON
        println "####################助手端我的############################"
        println json
        def sessionId = json['sessionId']
        if (sessionId == null || sessionId == '')
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        User user = User.findByAppSessionId(sessionId)
        if (!user)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
        }
        else
        {

            render user as JSON

            /*def result=[]
            result.add(user)
            if(user.department.name=="销售组")
            {
                //销售组统计本月评房，本月报单，已评房，已报单
                def info=[:]
                String sql="from Opportunity as o where "
                def opportunityList=Opportunity.findAll(sql)
                info["本月评房"]=opportunityList.size()
                info[""]=
                info[""]=
                info[""]=
                result.add(info)
            }
            render result as JSON*/
        }

    }

    @Transactional
    def appCreateContactTest()
    {
        //助手端,创建测试用联系人和商机关联人，测试使用。
        def contact = new Contact()
        if (contact.validate())
        {
            contact.type = "Agent"
            contact.fullName = "王毅"
            contact.idNumber = "110001199902020901"
            contact.cellphone = "13113113100"
            contact.maritalStatus = "已婚"
            contact.account = Account.findById(3)
            contact.userCode = "18811414141"
            contact.city = City.findByName("北京")
            contact.save flush: true
        }
        else
        {
            println contact.errors
        }

        contact = new Contact()
        if (contact.validate())
        {
            contact.type = "Client"
            contact.fullName = "王二"
            contact.idNumber = "110001199901010901"
            contact.cellphone = "13113113111"
            contact.maritalStatus = "已婚"
            contact.account = Account.findById(3)
            contact.save flush: true
        }
        else
        {
            println contact.errors
        }

        contact = new Contact()
        if (contact.validate())
        {
            contact.type = "Client"
            contact.fullName = "王三"
            contact.idNumber = "110001199903030901"
            contact.cellphone = "13113113122"
            contact.maritalStatus = "已婚"
            contact.account = Account.findById(3)
            contact.save flush: true
        }
        else
        {
            println contact.errors
        }

        contact = new Contact()
        if (contact.validate())
        {
            contact.type = "Client"
            contact.fullName = "王四"
            contact.idNumber = "110001199904040901"
            contact.cellphone = "13113113133"
            contact.maritalStatus = "已婚"
            contact.account = Account.findById(3)
            contact.save flush: true
        }
        else
        {
            println contact.errors
        }

        contact = new Contact()
        if (contact.validate())
        {
            contact.type = "Client"
            contact.fullName = "王五"
            contact.idNumber = "110001199905050901"
            contact.cellphone = "13113113144"
            contact.maritalStatus = "已婚"
            contact.account = Account.findById(3)
            contact.save flush: true
        }
        else
        {
            println contact.errors
        }

        render 1
    }

    @Transactional
    def sendVerifiedCode()
    {
        String username = params.username
        def user = User.findByUsername(username)
        if (user)
        {
            if (user?.loginBySms)
            {
                userService.sendVerificationCode(user)
                render([status: "success"] as JSON)
            }
            else
            {
                render([status: "error", errorMessage: message(code: '此账户不支持短信验证码，请使用口令登录!')] as JSON)
                return
            }
        }
        else
        {
            render([status: "error", errorMessage: message(code: '用户名不存在，请核对用户名!')] as JSON)
            return
        }
    }

    @Transactional
    def changeAvatar()
    {
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)
        respond user
    }

    @Transactional
    def changeAvatarSave()
    {
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)

        // 图片参数校验
        def file = request.getFile("file")
        if (file.empty)
        {
            flash.message = message(code: '请选择要上传的头像图片')
            redirect action: 'changeAvatar'
            return
        }
        def imageExtensionsList = ['jpg', 'png', 'jpeg', 'JPG', 'PNG', 'JPEG']
        def fileSize = request.getContentLength()
        if (fileSize > 5242880)
        {
            flash.message = message(code: '头像图片大小不能超过5M')
            redirect action: 'changeAvatar'
            return
        }
        def fileOrgName = file?.getOriginalFilename()
        def fileType = fileOrgName?.substring(fileOrgName.lastIndexOf(".") + 1)

        if (!(fileType in imageExtensionsList))
        {
            flash.message = message(code: '文件格式不支持')
            redirect action: 'changeAvatar'
            return
        }

        Company company = Company.findAll()[0]
        String fileServer = company?.fileServer

        // 将图片临时存储到 images目录中
        def webrootDir = servletContext.getRealPath("/")
        def code = UUID.randomUUID().toString()
        File fileImage = new File(webrootDir, "images/${code}.${fileType}")
        file.transferTo(fileImage)

        if (fileServer)
        {
            // 上传图片信息
            def param = [:]
            param.put("fileType", fileType)
            def fileName = fileServerService.upload(fileImage, param, fileServer)

            // 删除临时文件
            if (fileImage.isFile() && fileImage.exists())
            {
                fileImage.delete()
            }

            // 存储到文件服务器
            if (fileName)
            {
                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy")
                SimpleDateFormat sdf2 = new SimpleDateFormat("MM")
                SimpleDateFormat sdf3 = new SimpleDateFormat("dd")
                Date date = new Date()

                def year = sdf1.format(date)
                def month = sdf2.format(date)
                def day = sdf3.format(date)

                user.avatarUrl = fileServer + "/static/${year}/${month}/${day}/${fileName}.${fileType}"
            }
            else
            {
                flash.message = message(code: '调用上传文件服务失败，请稍后重试')
                redirect action: 'changeAvatar'
                return
            }
        }
        else
        {
            // 删除旧头像图片
            String oldAvatarUrl = user.avatarUrl
            if (oldAvatarUrl)
            {
                String oldAvatarUrlImage = oldAvatarUrl.substring(oldAvatarUrl.lastIndexOf("/") + 1)
                File oldFileImage = new File(webrootDir, "images/${oldAvatarUrlImage}")
                if (oldFileImage.isFile() && oldFileImage.exists())
                {
                    oldFileImage.delete()
                }
            }

            InetAddress address = InetAddress.getLocalHost()
            String hostAddress = address.getHostAddress()

            user.avatarUrl = "http://crm.cindata.cn/static/images/${code}.${fileType}"
        }

        def o = [:]
        def files = []
        def sfile = [:]
        sfile['thumbnailUrl'] = user.avatarUrl
        sfile['name'] = fileOrgName
        files.add(sfile)
        o['files'] = files

        if (user.validate())
        {
            user.save flush: true
            render o as JSON
        }
        else
        {
            flash.message = message(code: '文件上传失败，请稍后重试')
            redirect action: 'changeAvatar'
            return
        }
    }
}
